.TH E9TOOL "1" "April 2023" "E9Tool" "E9Tool"
.SH NAME
E9Tool \- a powerful static binary rewriting tool
.SH SYNOPSIS
e9tool [\fBOPTIONS\fR] -M \fBMATCH\fR -P \fBPATCH\fR \fIbinary\fR
.PP
Where
.IP "" 4
- \fBOPTIONS\fR are E9Tool options (see below)
.br
- \fBMATCH\fR specifies \fIwhich\fR instructions should be patched
.br
- \fBPATCH\fR specifies \fIhow\fR matching instructions should be patched
.br
- \fIbinary\fR is the binary name/path.
.SH DESCRIPTION
.PP
E9Tool is the default frontend for the E9Patch static rewriting system for
(stripped) x86_64 Linux ELF or Windows PE binaries.
E9Tool is designed to be more high-level and user friendly.
.PP
E9Tool implements the following basic work flow:
.IP "" 4
1. Disassemble the input \fIbinary\fR
.br
2. Find all instructions matching \fBMATCH\fR
.br
3. Generate low-level E9Patch commands for \fBPATCH\fR
.br
4. Invoke E9Patch with the commands to rewrite the \fIbinary\fR
.PP
The output binary will be written to \fIa.out\fR by default, or a
filename specified by the \fB-o\fR option (see below).
.PP
For the \fBMATCH\fR and \fBPATCH\fR specification languages, as well as other
advanced E9Tool usage, please refer to the following document:
.IP "" 4
\fI/usr/share/doc/e9tool/e9tool-user-guide.html\fR
.SH EXAMPLE USAGE
For this example, we will rewrite the \fIxterm\fR binary with
instrumentation that prints information to the terminal.
The instrumentation is implemented in the \fIprint.c\fR file available here:
.IP "" 4
/usr/share/e9tool/examples/print.c
.PP
Here, the \fIprint.c\fR file exports the following function:
.nf
.sp
    #include \fB"stdlib.c"\fR
    void \fIentry\fR(const void *\fIaddr\fR,
               const uint8_t *\fIinstr\fR,
               size_t \fIsize\fR,
               const char *\fIasm\fR)
    {
        ...
    }
.fi
.PP
Here:
.IP "" 4
- \fB"stdlib.c"\fR is the standard library (for printf, etc.)
.br
- \fIaddr\fR is the instruction address
.br
- \fIinstr\fR is the instruction bytes
.br
- \fIsize\fR is the size of the instruction
.br
- \fIasm\fR is the disassembly string of the instruction
.PP
Next, the instrumentation is compiled using the \fBe9compile\fR
script:
.IP "" 4
$ e9compile /usr/share/e9tool/examples/print.c
.PP
This generate a small binary named \fIprint\fR.
Next, we use \fBe9tool\fR to instrument the \fIxterm\fR program as follows:
.IP "" 4
$ e9tool -M 'asm=/xor.*/' -P 'entry(addr,instr,size,asm)@print' \fIxterm\fR
.PP
Here:
.IP "" 4
- the "\fB-M ...\fR" option matches all "xor" instructions
.br
- the "\fB-P ...\fR" option patches all matching xor instructions.
.PP
The patch will instrument all matching xor instructions will a call to
\fIentry()\fR from \fIprint\fR.
For each matching instruction, E9Tool will also pass the
corresponding values for each parameter of \fIentry()\fR.
.PP
The rewritten (instrumented) binary will be written to \fIa.out\fR,
and can be executed as follows:
.IP "" 4
$ ./\fIa.out\fR
.PP
The rewritten binary will run the same as the original,
but will also print information for each xor instruction that is executed.
.PP
This is a basic example, and E9Tool supports several options and use cases.
For more information, please refer to the following document:
.IP "" 4
\fI/usr/share/doc/e9tool/e9tool-user-guide.html\fR
.SH OPTIONS
.IP "\fB\-100\fR" 4
Enables "full coverage" mode that attempts to patch 100% of matching
instructions, even at the cost of a significant reduction in performance.
This is useful for applications that prioritize coverage over other
considerations.
.IP "\fB\-\-backend\fR PROG" 4
Use PROG as the backend.
The default is "e9patch".
.IP "\fB\-CFR\fr, \fB\-X\fR" 4
Enables binary rewriting "with" control-flow recovery.  This
usually makes the rewritten binary much faster, but may
introduce rewriting bugs if the built-in recovery analysis is
inaccurate.
.IP "\fB\-\-compression\fR N, \fB\-c\fR N" 4
Set the compression level to be N, where N is a number within
the range 0..9.  The default is 9 for maximum compression.
Higher compression makes the output binary smaller, but also
increases the number of mappings (mmap() calls) required.
.IP "\fB\-\-Dsync\fR N" 4
If the disassembler desyncs (e.g., data in the code section),
then automatically exclude N surrounding instructions.
The default is 64.
.IP "\fB\-\-Dthreshold\fR N" 4
Treat suspicious instructions as data.
Lower numbers means less tolerance.
The default is 2.
.IP "\fB\-\-debug\fR" 4
Enable debug output.
.IP "\fB\-\-dump\-all\fR" 4
Dump all analysis information (disasm, targets, BBs, funcs)
into CSV files of the form "\fBOUTPUT.TYPE.csv\fR", where:
.IP
\- \fBOUTPUT\fR is the output binary name, and
.br
\- \fBTYPE\fR is one of {DISASM,TARGETs,BBs,FUNCs}.
.IP
The generated files are compatible with \fB--use-disasm\fR/\fB--use-targets\fR.
.IP "\fB\-\-exclude\fR RANGE, \fB\-E\fR RANGE" 4
Exclude the address RANGE from disassembly and rewriting.
Here, RANGE has the format `LB .. UB', where LB/UB are
integer addresses, section names or symbols.  The address
range [LB..UB) will be excluded, and UB must point to the
first instruction where disassembly should resume.
.IP "\fB\-\-executable\fR" 4
Treat the input file as an executable, even if it appears to
be a shared library.  See the `\-\-shared' option for more
information.
.IP "\fB\-\-format\fR FORMAT" 4
Set the output format to FORMAT which is one of {binary,
json, patch, patch.gz, patch,bz2, patch.xz}.  Here:
.IP
\- "binary" is a modified ELF executable file;
.br
\- "json" is the raw JSON RPC stream for the e9patch
backend; or
.br
\- "patch" "patch.gz" "patch.bz2" and "patch.xz"
are (compressed) binary diffs in xxd format.
.IP
The default format is "binary".
.IP "\fB\-\-help\fR, \fB\-h\fR" 4
Print the help message and exit.
.IP "\fB\-\-no\-warnings\fR" 4
Do not print warning messages.
.IP "\fB\-\-plt\fR" 4
Enable the disassembly/rewriting of the .plt.* sections which
are excluded by default.
.IP "\fB\-\-plugin\fR=NAME:OPTION"
Pass OPTION to the plugin with NAME.
Here NAME must identify a
plugin used by a matching or patching operation.
.IP "\fB\-O0\fR, \fB\-O1\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR"
Set the optimization level.
Here:
.IP
\fB\-O0\fR disables all optimization
.br
\fB\-O1\fR conservatively optimizes for performance
.br
\fB\-O2\fR optimizes for performance
.br
\fB\-O3\fR aggressively optimizes for performance
.br
\fB\-Os\fR optimizes for space
.IP
The default is \fB\-O2\fR.
.IP "\fB\-\-option\fR OPTION" 4
Pass OPTION to the e9patch backend.
.IP "\fB\-\-output\fR FILE, \fB\-o\fR FILE" 4
Specifies the path to the output file.
The default filename is
one of {"a.out", "a.so", "a.exe", "a.dll"}, depending on
the input binary type.
.IP "\fB\-\-seed\fR=\fI\,SEED\/\fR" 4
Set SEED as the random number seed.  The special value "0"
chooses a random seed.
.IP "\fB\-\-shared\fR" 4
Treat the input file as a shared library, even if it appears to
be an executable.  By default, the input file will only be
treated as a shared library if (1) it is a dynamic executable
(ET_DYN) and (2) has a filename of the form:
.IP
[PATH/]lib*.so[.VERSION]
.IP "\fB\-\-static\-loader\fR, \fB\-s\fR" 4
Replace patched pages statically.
By default, patched pages
are loaded during program initialization as this is more
reliable for large/complex binaries.  However, this may bloat
the size of the output patched binary.
.IP "\fB\-\-syntax\fR SYNTAX" 4
Selects the assembly syntax to be SYNTAX.
Possible values are:
.IP
"ATT": X86_64 ATT asm syntax
.br
"intel": X86_64 Intel asm syntax
.IP
The default syntax is "ATT".
.IP "\fB\-\-trap\fR=\fI\,ADDR\/\fR, \fB\-\-trap\-all\fR" 4
Insert a trap (int3) instruction at the corresponding
trampoline entry.  This can be used for debugging with gdb.
.IP "\fB\-\-use\-disasm \fI\,FILE\/\fR" 4
Use the instruction information in FILE rather than the default
disassmebler.  Here, FILE is a CSV file with a single column
representing instruction addresses.
.IP "\fB\-\-use\-targets \fI\,FILE\/\fR" 4
Use the jump/call target information in FILE rather than the
default control-flow recovery analysis.  Here, FILE is a CSV
file where the first column is all jump/call targets, and
columns 2,3,4 are Boolean values (1 or 0) representing the
target type (2=direct, 3=indirect, and 4=function).
.IP "\fB\-\-version\fR" 4
Print the version and exit.
.SH "SEE ALSO"
\fIe9patch\fR(1), \fIe9compile\fR(1), \fIe9afl\fR(1), \fIredfat\fR(1)
.SH AUTHOR
\fBe9patch\fR is written by Gregory J. Duck <gregory@comp.nus.edu.sg>.
